Popular Searches
Popular Course Categories
Popular Courses

Understanding Component Scanning and Stereotype Annotations

Understanding Component Scanning and Stereotype Annotations

Spring Framework and Dependency Injection

Understanding Component Scanning and Stereotype Annotations in Spring Framework

Course: Advance Java Training

Topic: Understanding Component Scanning and Stereotype Annotations

Course Link: Advance Java Training Course

Demo Link: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction

Component scanning and stereotype annotations are important features of the Spring Framework that simplify bean registration and application configuration. They allow Spring to discover classes automatically, register eligible classes as Spring-managed beans, and organize application components according to their responsibilities.

Without component scanning, developers may need to declare many application objects individually through XML configuration or Java-based @Bean methods. Component scanning reduces this manual work by identifying eligible classes on the classpath.

Stereotype annotations such as @Component, @Service, @Repository, and @Controller identify classes according to their roles in an application. Spring can detect these annotations during scanning and register corresponding bean definitions in the application context. Read the official Spring documentation on classpath scanning.

2. Learning Objectives

  • Understand component scanning and its purpose.
  • Learn how Spring discovers and registers beans automatically.
  • Understand the purpose of stereotype annotations.
  • Differentiate between @Component, @Service, @Repository, and @Controller.
  • Learn how to configure scanning with @ComponentScan.
  • Understand component scanning in Spring Boot applications.
  • Learn how to assign custom bean names.
  • Configure include and exclude filters.
  • Identify common component-scanning errors and troubleshoot them.

3. What Is a Spring Bean?

A Spring bean is an object instantiated, configured, and managed by the Spring IoC (Inversion of Control) container. The container manages the bean's dependencies and lifecycle according to the application's configuration.

For example, an application may contain a payment service, a customer repository, and a controller. These classes can be registered as Spring beans so that their dependencies can be injected automatically.

Example

import org.springframework.stereotype.Component;

@Component
public class GreetingService {

    public void greet() {
        System.out.println("Welcome to Spring Framework!");
    }
}

The @Component annotation marks GreetingService as a candidate for automatic detection. When component scanning is enabled for the package containing this class, Spring can register it as a bean.

4. What Is Component Scanning?

Component scanning is a Spring mechanism that searches specified packages for eligible classes and registers their bean definitions with the application context.

Spring examines classes in the configured scanning locations and checks whether they match its component-detection rules. Classes annotated with supported stereotype annotations can then become Spring-managed beans.

How Component Scanning Works

  1. The application starts and loads its Spring configuration.
  2. Spring identifies the packages configured for scanning.
  3. The scanner examines eligible classes within those packages.
  4. Spring identifies classes matching its component-detection rules.
  5. Bean definitions are registered in the application context.
  6. The container creates bean instances when required by the configured scope and initialization strategy.
  7. Dependencies are resolved and injected according to the application's configuration.
  8. The beans become available to other components through dependency injection or container lookups.

Component Scanning Flow

Spring Application Starts
          |
          v
Load Configuration
          |
          v
Identify Base Packages
          |
          v
Scan Eligible Classes
          |
          v
Detect Stereotype Annotations
          |
          v
Register Bean Definitions
          |
          v
Create and Configure Beans
          |
          v
Dependency Injection
          |
          v
Application Components Ready

5. Advantages of Component Scanning

  • Less configuration: Reduces the need to declare every component manually.
  • Automatic registration: Eligible classes can become beans through annotations.
  • Cleaner code: Component roles are declared close to their class definitions.
  • Maintainability: New classes can be discovered without adding a separate bean declaration for each one.
  • Dependency injection support: Registered components can receive their dependencies from Spring.
  • Layered architecture: Stereotypes help distinguish controllers, services, and repositories.

6. What Are Stereotype Annotations?

Stereotype annotations identify the general role of a class in an application. Spring provides annotations that make classes eligible for automatic detection and communicate their responsibilities to developers and framework tools.

The main stereotype annotations are:

  • @Component
  • @Service
  • @Repository
  • @Controller
  • @RestController, a composed annotation used for REST endpoints

@Service, @Repository, and @Controller are specialized stereotypes built on @Component. @RestController combines controller semantics with response-body behavior. These annotations help Spring recognize application components and, where applicable, apply specialized framework behavior.

7. Understanding @Component

The @Component annotation is the general-purpose stereotype for a Spring-managed component. Use it when a class needs to be managed by Spring but does not fit a more specific stereotype.

Example

import org.springframework.stereotype.Component;

@Component
public class EmailFormatter {

    public String format(String message) {
        return "Email message: " + message;
    }
}

When Spring scans the relevant package, it can discover EmailFormatter and register it as a bean.

When to Use @Component

  • Utility components managed by Spring.
  • Formatting or conversion helpers.
  • Reusable application components that do not belong to a more specific layer stereotype.
  • Custom components that participate in dependency injection.

8. Understanding @Service

The @Service annotation identifies a class that implements application or business logic. It communicates that the class belongs to the service layer.

Example

import org.springframework.stereotype.Service;

@Service
public class CustomerService {

    public String getCustomerMessage() {
        return "Customer information processed.";
    }
}

Spring can discover this class during component scanning. Although @Service is a specialization of @Component, its explicit meaning improves readability and makes the application's architecture easier to understand.

Typical Responsibilities

  • Implementing business rules.
  • Coordinating operations across repositories or other services.
  • Validating business-level conditions.
  • Managing application workflows.
  • Serving as a boundary for transaction-related business operations when configured appropriately.

9. Understanding @Repository

The @Repository annotation identifies a class responsible for data access or persistence. Repository components typically interact with databases through technologies such as JDBC, JPA, or other persistence APIs.

Example

import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;

@Repository
public class CustomerRepository {

    public List<String> findAllCustomers() {
        List<String> customers = new ArrayList<>();
        customers.add("Aarav");
        customers.add("Meera");
        return customers;
    }
}

This example uses an in-memory list for illustration. A production repository would usually interact with a database or persistence framework.

Why Use @Repository?

  • Clearly identifies the persistence layer.
  • Allows the class to be discovered through component scanning.
  • Supports Spring's persistence exception-translation infrastructure when the relevant configuration and persistence integration are present.
  • Improves separation between data access and business logic.

10. Understanding @Controller

The @Controller annotation identifies a Spring MVC controller. Controllers receive web requests, coordinate request handling, and commonly return view names or model information.

Example

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/home")
    public String home() {
        return "home";
    }
}

In a Spring MVC application configured for view resolution, returning "home" typically identifies the view to render. This example assumes the necessary MVC configuration and view template are available.

Responsibilities

  • Mapping web requests to handler methods.
  • Receiving and validating request input with appropriate validation configuration.
  • Preparing model data for views.
  • Returning view names or other supported MVC results.

11. Understanding @RestController

The @RestController annotation is commonly used to build REST APIs. It combines @Controller with @ResponseBody behavior, meaning handler return values are written to the HTTP response body through the configured message converters instead of being interpreted as view names.

Example

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {

    @GetMapping("/api/message")
    public String getMessage() {
        return "Customer API is running.";
    }
}

When the endpoint is requested in a properly configured Spring MVC application, the returned string is written to the response body.

12. Comparison of Stereotype Annotations

Annotation Purpose Typical Layer Example Class
@Component General Spring-managed component Any suitable layer EmailFormatter
@Service Application and business logic Service layer CustomerService
@Repository Data access and persistence Repository layer CustomerRepository
@Controller Web request handling and MVC views Presentation layer HomeController
@RestController REST endpoint handling with response-body behavior Web/API layer CustomerApiController

Choose the annotation that best represents the class's responsibility. Although several stereotypes can make a class eligible for scanning, using the correct one improves clarity and can enable relevant framework features.

13. Configuring Component Scanning with @ComponentScan

The @ComponentScan annotation tells Spring which packages to scan for components. It is commonly placed on a class annotated with @Configuration.

Example

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

Spring scans the com.example package and its subpackages for eligible components, subject to the scanner's configured filters and rules.

Scanning Multiple Packages

@Configuration
@ComponentScan(basePackages = {
    "com.example.service",
    "com.example.repository",
    "com.example.controller"
})
public class AppConfig {
}

Multiple package roots can be specified when an application separates components into different package trees.

Using basePackageClasses

Instead of using package-name strings, you can specify marker classes to identify package locations.

@Configuration
@ComponentScan(basePackageClasses = {
    CustomerService.class,
    CustomerRepository.class
})
public class AppConfig {
}

This approach can reduce errors caused by package-name typos. The package containing each marker class becomes a scanning location.

14. Component Scanning in Spring Boot

Spring Boot commonly enables component scanning through @SpringBootApplication, which includes @ComponentScan behavior along with configuration and auto-configuration features.

Example

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

By default, component scanning starts from the package containing the application class and includes its subpackages. For example, if MyApplication is in com.example, components in com.example.service and com.example.repository can be discovered automatically.

Recommended Package Structure

com.example
├── MyApplication.java
├── controller
│   └── CustomerController.java
├── service
│   └── CustomerService.java
├── repository
│   └── CustomerRepository.java
└── model
    └── Customer.java

Keeping the main Spring Boot application class in a common parent package often makes scanning straightforward. If components are placed outside that package tree, configure scanning explicitly or reorganize the package structure.

15. Complete Example: Component Scanning and Dependency Injection

This example shows how a controller-like application component can receive a service bean through constructor injection. It uses a simple non-web configuration so the scanning behavior can be tested without starting a web server.

CustomerService.java

package com.example.service;

import org.springframework.stereotype.Service;

@Service
public class CustomerService {

    public String getMessage() {
        return "Customer service is working.";
    }
}

CustomerMessage.java

package com.example.component;

import com.example.service.CustomerService;
import org.springframework.stereotype.Component;

@Component
public class CustomerMessage {

    private final CustomerService customerService;

    public CustomerMessage(CustomerService customerService) {
        this.customerService = customerService;
    }

    public String displayMessage() {
        return customerService.getMessage();
    }
}

AppConfig.java

package com.example.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

Main.java

package com.example;

import com.example.component.CustomerMessage;
import com.example.config.AppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) {
        try (AnnotationConfigApplicationContext context =
                 new AnnotationConfigApplicationContext(AppConfig.class)) {

            CustomerMessage message =
                context.getBean(CustomerMessage.class);

            System.out.println(message.displayMessage());
        }
    }
}

Expected Output

Customer service is working.

In this example, Spring discovers both classes through component scanning. It registers the beans, resolves the constructor dependency, and supplies the CustomerService instance to CustomerMessage.

16. Assigning Custom Bean Names

Spring generates a default bean name for a component detected through scanning. Typically, the default is the uncapitalized simple class name. You can specify an explicit name through the stereotype annotation's value attribute.

Example

import org.springframework.stereotype.Service;

@Service("paymentService")
public class PaymentService {

    public void processPayment() {
        System.out.println("Payment processed.");
    }
}

The bean can be retrieved by its explicit name:

PaymentService service =
    context.getBean("paymentService", PaymentService.class);

service.processPayment();

Use explicit names when there is a clear reason to do so. If the application has multiple beans of the same type, consider using qualifiers or other appropriate dependency-injection configuration rather than relying on names everywhere.

17. Include and Exclude Filters

Spring allows you to customize which classes component scanning includes or excludes. Filters are useful when an application needs to discover only selected components or avoid registering certain classes.

Example: Excluding a Component by Annotation

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Repository;

@Configuration
@ComponentScan(
    basePackages = "com.example",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = Repository.class
    )
)
public class AppConfig {
}

This configuration excludes classes marked with @Repository from this scan. Use exclusions carefully because services may depend on repository beans that are no longer registered.

Common Filter Types

Filter Type Purpose
ANNOTATION Matches classes carrying a specified annotation.
ASSIGNABLE_TYPE Matches a specified class or types assignable to it.
ASPECTJ Matches types using an AspectJ type expression.
REGEX Matches class names using a regular expression.
CUSTOM Uses a custom filter implementation.

18. Custom Stereotype Annotations

Spring supports custom stereotype annotations. These are useful when a project needs a specialized annotation to identify a particular category of component while retaining Spring's component-scanning behavior.

Example

import org.springframework.stereotype.Component;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface BusinessComponent {
}

A class can then use the custom annotation:

@BusinessComponent
public class InvoiceProcessor {

    public void processInvoice() {
        System.out.println("Invoice processed.");
    }
}

Because @BusinessComponent is annotated with @Component, Spring can recognize it as a stereotype during component scanning. Custom stereotypes can make a large application more expressive, but should be introduced only when they provide a clear architectural benefit.

19. Component Scanning vs. @Bean Configuration

Component scanning and explicit bean configuration are two ways to register objects with Spring. They can be used together in the same application.

Feature Component Scanning @Bean Configuration
How it works Discovers eligible annotated classes in configured packages. Registers the object returned by a configuration method.
Typical use Application classes that you control. Third-party classes or objects requiring explicit construction.
Configuration style Annotations on component classes plus scanning configuration. Methods inside a configuration class.
Control over creation Relies on component registration and dependency-injection rules. Provides explicit control over how the object is constructed.

Example of @Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ServiceConfig {

    @Bean
    public String applicationMessage() {
        return "Welcome to Spring";
    }
}

Use component scanning for discoverable application components and @Bean methods when explicit object construction or third-party integration is appropriate.

20. Common Component Scanning Errors

Error Possible Cause Solution
Bean not found The class is outside the configured scanning packages. Adjust @ComponentScan or move the class into the correct package tree.
No qualifying bean No matching bean was registered or multiple candidates exist. Check scanning, component annotations, bean types, qualifiers, and configuration.
Duplicate bean name Different components use the same explicit name. Choose unique bean names or review the configuration.
Unsatisfied dependency A constructor dependency has no suitable registered bean. Register the dependency and confirm its package is scanned.
Unexpected bean registration A broad scan includes unwanted components. Narrow the scan packages or configure appropriate filters.
Controller endpoint unavailable Controller scanning or web configuration is incomplete. Check package placement, MVC configuration, request mappings, and server startup.
Custom stereotype ignored The custom annotation lacks the necessary component meta-annotation or runtime retention. Verify the custom annotation definition and scanning configuration.

21. Best Practices

  • Use @Component for general-purpose Spring-managed components.
  • Use @Service for business logic and application workflows.
  • Use @Repository for persistence and data access classes.
  • Use @Controller for MVC controllers and @RestController for REST APIs.
  • Keep the Spring Boot application class in a sensible root package so related components are scanned automatically.
  • Prefer constructor injection for required dependencies.
  • Keep component-scanning package boundaries clear and intentional.
  • Use custom bean names only when they provide useful clarity or resolve a genuine naming requirement.
  • Use include and exclude filters only when the default scanning behavior is insufficient.
  • Avoid annotating every class indiscriminately; register only objects that benefit from Spring management.
  • Test application-context startup to detect missing or conflicting beans early.
  • Separate controllers, services, and repositories to improve maintainability and testing.

22. Practical Exercises

Exercise 1: Create a Service Component

  1. Create a class named GreetingService.
  2. Annotate it with @Service.
  3. Add a method that returns a greeting message.
  4. Enable component scanning for its package.
  5. Retrieve the service from the Spring context and invoke the method.

Exercise 2: Create a Repository Component

  1. Create a ProductRepository class.
  2. Annotate it with @Repository.
  3. Add a method that returns sample product data.
  4. Inject the repository into a ProductService class.
  5. Verify that the service can retrieve the data.

Exercise 3: Configure Component Scanning

  1. Create separate packages for controllers, services, and repositories.
  2. Configure @ComponentScan for their common parent package.
  3. Register one component in each package.
  4. Verify that Spring discovers all expected beans.
  5. Change the base package temporarily and observe the effect.

23. Interview Questions and Answers

Q1. What is component scanning in Spring?

Component scanning is the process of searching configured packages for eligible components and registering their bean definitions with the Spring container.

Q2. What is a stereotype annotation?

A stereotype annotation identifies a class's role and can make it eligible for automatic detection during component scanning.

Q3. What is the purpose of @Component?

@Component is the general-purpose stereotype used to identify a Spring-managed component.

Q4. What is the difference between @Component and @Service?

@Component is generic, while @Service communicates that the class belongs to the service layer. Both can be discovered through component scanning.

Q5. Why is @Repository used?

@Repository identifies persistence-layer components and can participate in Spring's persistence exception-translation support when properly configured.

Q6. What is the difference between @Controller and @RestController?

@Controller is commonly used for MVC request handling and view resolution. @RestController combines controller behavior with response-body behavior for REST-style endpoints.

Q7. What does @ComponentScan do?

@ComponentScan specifies package locations and scanning rules for discovering eligible components.

Q8. How does Spring Boot enable component scanning?

@SpringBootApplication includes component-scanning behavior. By default, scanning starts from the package containing the application class and includes its subpackages.

Q9. Can a component have a custom bean name?

Yes. A stereotype annotation can specify a bean name, such as @Service("paymentService").

Q10. Can component scanning and @Bean methods be used together?

Yes. They are complementary registration mechanisms and are commonly used together in Spring applications.

Q11. Why might Spring fail to find a component?

The class may be outside the scanning packages, lack an eligible component annotation, be excluded by a filter, or fail during application configuration.

Q12. What is a custom stereotype annotation?

It is a project-defined annotation, typically meta-annotated with @Component, that gives a specialized meaning to a category of Spring-managed classes.

24. Quick Revision Checklist

  • Spring bean: An object managed by the Spring IoC container.
  • Component scanning: Discovers eligible classes in configured packages.
  • @Component: General-purpose component stereotype.
  • @Service: Service-layer stereotype.
  • @Repository: Persistence-layer stereotype.
  • @Controller: Spring MVC controller stereotype.
  • @RestController: Controller with response-body behavior.
  • @ComponentScan: Configures package scanning and filters.
  • @SpringBootApplication: Enables Spring Boot application configuration, auto-configuration, and component scanning.
  • Custom bean name: Can be provided through a stereotype annotation's name/value attribute.
  • Custom stereotype: Can be created using a component meta-annotation.
  • @Bean: Explicitly registers an object returned by a configuration method.

25. Conclusion

Component scanning and stereotype annotations reduce manual configuration and make Spring applications easier to organize. Component scanning discovers eligible classes, while annotations such as @Component, @Service, @Repository, and @Controller describe their responsibilities.

By configuring scan locations correctly, choosing meaningful stereotypes, using constructor injection, and following a clear package structure, developers can build maintainable applications with reliable dependency injection and bean management.

Learn More with JustAcademy

Explore the Advance Java Training Course to strengthen your understanding of Spring Framework, dependency injection, component scanning, and Java application development.

Register for a Course Demo to learn more about the training program.

Visit the JustAcademy website to explore additional courses and learning resources.

Previous Next
whatsapp